# 电影节点所需要的属性
def node_struct_for_movie(obj):
  # obj['revenue']:这个数值过大的时候会为'bson.int64.Int64',需要转化成python的int
  obj['revenue'] = int(obj['revenue'])
  return {
    'id': obj['id'],
    'overview': obj['overview'],
    'popularity': obj['popularity'],
    'release_date': obj['release_date'],
    'revenue': obj['revenue'],
    'title': obj['title'],
    # 'title_en': obj['title_en'],
    # 这里加多一个name，为英文电影名称
    'name': obj['title'],

    'vote_average': obj['vote_average'],
    'vote_count': obj['vote_count'],
  }

# 人员节点所需要的属性
def node_struct_for_crew(obj):
  return {
    'id': obj['id'],
    'name': obj['name'],
    'job': obj['job'],
  }


def add_data_in_list(target_set, data, target_list, key='id'):
  length = len(data)
  for i in range(length):
    obj = data[i]
    if obj[key] not in target_set:
      target_set.add(obj[key])
      target_list.append(obj)

# 对movie_info的数据处理
def process_data_for_movie_info(origin_data_movie_info, invalid_movie_id_set):
  length = len(origin_data_movie_info)
  movie_list = []
  origin_language_list = []

  genre_list = []
  production_company_list = []
  production_country_list = []

  # 下面的set都是用来存储id用于辨别是否重复
  origin_language_set = set()
  genre_set = set()
  production_company_set = set()
  production_country_set = set()

  for index in range(length):
    item = origin_data_movie_info[index]
    # 有些没有数据
    if 'id' not in item:
      continue
    # 缺失值处理，如果没有人评分过的电影，直接过滤掉
    if item['vote_count'] == 0:
      invalid_movie_id_set.add(item['id'])
      continue
    movie_obj = node_struct_for_movie(item)
    movie_list.append(movie_obj)
    origin_language_set.add(item['original_language'])

    # 处理类型,过滤重复的值
    add_data_in_list(genre_set, item['genres'], genre_list)
    add_data_in_list(production_company_set, item['production_companies'], production_company_list)
    add_data_in_list(production_country_set, item['production_countries'], production_country_list, key='iso_3166_1')
  
  origin_language_list = list(origin_language_set)

  return {
    'movie_list': movie_list,
    'genre_list': genre_list,
    'origin_language_list': origin_language_list,
    'production_company_list': production_company_list,
    'production_country_list': production_country_list,
  }

# 处理关键词数据：去重
def process_data_for_movie_keyword(origin_data_movie_keywords, invalid_movie_id_set):
  # 存储keyword的id,避免重复
  all_keyword_id_set = set()
  all_keyword_list = []
  for obj in origin_data_movie_keywords:
    # 部分数据有问题
    if 'id' not in obj or obj['id'] in invalid_movie_id_set:
      continue
    keywords = obj['keywords']
    for item in keywords:
      if item['id'] not in all_keyword_id_set:
        all_keyword_id_set.add(item['id'])
        all_keyword_list.append(item)
  return all_keyword_list

# 处理演员数据以及制作人员数据：去重
def process_data_for_movie_crew(origin_data_movie_credits, invalid_movie_id_set):
  crew_id_set = set()
  crew_list = []
  # 这里我们只保存三种制作人员
  # 1.Producer，2.Director，3.Writer
  valid_job_list = ['Producer', 'Director', 'Writer']
  for obj in origin_data_movie_credits:
    if 'id' not in obj or obj['id'] in invalid_movie_id_set:
      continue
    crews = obj['crew']
    for item in crews:
      if item['job'] not in valid_job_list:
        continue
      if item['id'] not in crew_id_set:
        crew_id_set.add(item['id'])
        crew_obj = node_struct_for_crew(item)
        crew_list.append(crew_obj)
  return crew_list

'''
以下是关于处理实体关系的函数
'''
# 处理movie_id对多个id的情况
def process_relationship_movie_id_to_other_id_list(obj, key, other_id_list, item_key='id'):
  temp_id_list = []
  target_list = obj[key]
  for item in target_list:
    # production_countries没有id，用iso_3166_1表示
    temp_id_list.append(item[item_key])
  other_id_list.append({
    "movie_id": obj['id'],
    f"{key}": temp_id_list
  })
# 电影-类型:movie-genre
def process_data_for_relationship_movie_info(origin_data_movie_info):
  movie_id_to_genre_id_list = []
  movie_id_to_origin_language = []
  movie_id_to_production_company_id = []
  movie_id_to_production_country_id = []

  for obj in origin_data_movie_info:
    if 'id' not in obj or obj['vote_count'] == 0:
      continue
    process_relationship_movie_id_to_other_id_list(obj, 'genres', movie_id_to_genre_id_list)
    process_relationship_movie_id_to_other_id_list(obj, 'production_companies', movie_id_to_production_company_id)
    process_relationship_movie_id_to_other_id_list(obj, 'production_countries', movie_id_to_production_country_id, item_key='iso_3166_1')
    movie_id_to_origin_language.append({
      'movie_id': obj['id'],
      'original_language': obj['original_language']
    })
  return {
    'movie_id_to_genre_id_list': movie_id_to_genre_id_list,
    'movie_id_to_production_company_id_list': movie_id_to_production_company_id,
    'movie_id_to_production_country_id_list': movie_id_to_production_country_id,
    'movie_id_to_original_language_list': movie_id_to_origin_language,
  }


def process_data_for_relationship_movie_keyword(origin_data_movie_keywords, invalid_movie_id_set):
  result = []
  for item in origin_data_movie_keywords:
    if 'id' not in item or item['id'] in invalid_movie_id_set:
      continue
    movie_id = item['id']
    keyword_id_list = []
    keywords = item['keywords']
    for keyword_item in keywords:
      keyword_id_list.append(keyword_item['id'])
    result.append({
      'movie_id': movie_id,
      'keywords': keyword_id_list
    })
  return result

def process_data_for_relationship_movie_crew(origin_data_movie_credits, invalid_movie_id_set):
  movie_id_to_crew_id_list = []
  # 这里我们只保存三种制作人员
  # 1.Producer，2.Director，3.Writer
  valid_job_list = ['Producer', 'Director', 'Writer']
  for item in origin_data_movie_credits:
    if 'id' not in item or item['id'] in invalid_movie_id_set:
      continue
    movie_id = item['id']
    crew_id_list = []
    crews = item['crew']
    for crew in crews:
      job = crew['job']
      if job not in valid_job_list:
        continue
      crew_id_list.append(crew['id'])
    movie_id_to_crew_id_list.append({
      'movie_id': movie_id,
      'crew_id_list': crew_id_list
    })

  return movie_id_to_crew_id_list